import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:sensors_plus/sensors_plus.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '多小球碰撞物理系统',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: Gyro2DRollingBall(),
    );
  }
}

/// 小球数据模型类
class Ball {
  double posX; // X轴位置
  double posY; // Y轴位置
  double rotation; // 旋转角度
  double velX; // X轴速度
  double velY; // Y轴速度
  Color color; // 小球颜色
  double size; // 小球大小
  bool isSelected; // 是否被选中
  int collisionCount = 0; // 碰撞次数
  List<Offset> collisionHistory = []; // 碰撞位置记录

  // 新增：小球速度特性
  double maxSpeed; // 最大速度限制
  double accelerationFactor; // 加速度系数
  double frictionFactor; // 摩擦系数
  bool isSpeedLocked; // 速度是否锁定

  Ball({
    required this.posX,
    required this.posY,
    this.rotation = 0.0,
    this.velX = 0.0,
    this.velY = 0.0,
    required this.color,
    required this.size,
    this.isSelected = false,
    // 新增参数，提供默认值
    this.maxSpeed = 20.0,
    this.accelerationFactor = 1.0,
    this.frictionFactor = 1.0,
    this.isSpeedLocked = false,
  });

  /// 复制小球
  Ball copyWith({
    double? posX,
    double? posY,
    double? rotation,
    double? velX,
    double? velY,
    Color? color,
    double? size,
    bool? isSelected,
    double? maxSpeed,
    double? accelerationFactor,
    double? frictionFactor,
    bool? isSpeedLocked,
  }) {
    return Ball(
      posX: posX ?? this.posX,
      posY: posY ?? this.posY,
      rotation: rotation ?? this.rotation,
      velX: velX ?? this.velX,
      velY: velY ?? this.velY,
      color: color ?? this.color,
      size: size ?? this.size,
      isSelected: isSelected ?? this.isSelected,
      maxSpeed: maxSpeed ?? this.maxSpeed,
      accelerationFactor: accelerationFactor ?? this.accelerationFactor,
      frictionFactor: frictionFactor ?? this.frictionFactor,
      isSpeedLocked: isSpeedLocked ?? this.isSpeedLocked,
    );
  }

  /// 记录碰撞
  void recordCollision(double x, double y) {
    collisionHistory.add(Offset(x, y));
    collisionCount++;
    if (collisionHistory.length > 10) {
      collisionHistory.removeAt(0);
    }
  }

  /// 获取当前速度大小
  double get currentSpeed => sqrt(velX * velX + velY * velY);

  /// 获取速度描述
  String get speedDescription {
    double speed = currentSpeed;
    if (speed < 1.0) return '静止';
    if (speed < 5.0) return '缓慢';
    if (speed < 10.0) return '中速';
    if (speed < 15.0) return '快速';
    return '极速';
  }
}

class Gyro2DRollingBall extends StatefulWidget {
  @override
  _Gyro2DRollingBallState createState() => _Gyro2DRollingBallState();
}

class _Gyro2DRollingBallState extends State<Gyro2DRollingBall> {
  // ========== 小球和容器参数 ==========
  final double containerWidth = 300.0;
  final double containerHeight = 500.0;

  // ========== 多小球系统参数 ==========
  List<Ball> _balls = [];
  int _selectedBallIndex = 0;
  final int _maxBalls = 10;

  // ========== 传感器数据 ==========
  double _accelX = 0.0;
  double _accelY = 0.0;
  double _filteredAccelX = 0.0;
  double _filteredAccelY = 0.0;

  // ========== 物理模拟参数 ==========
  double _baseFriction = 0.93;
  double _sensitivity = 0.8;
  double _collisionElasticity = 0.8;

  // ========== 系统控制变量 ==========
  StreamSubscription<AccelerometerEvent>? _accelerometerSubscription;
  Timer? _physicsTimer;
  bool _is2DMode = true;
  final Random _random = Random();

  @override
  void initState() {
    super.initState();
    _initializeBalls();
    _resetPosition();
    _startGyroMode();
  }

  /// 初始化小球系统 - 增强版，每个小球有不同的速度特性
  void _initializeBalls() {
    _balls.clear();

    final List<Color> ballColors = [
      Colors.red,
      Colors.blue,
      Colors.green,
      Colors.orange,
      Colors.purple,
      Colors.teal,
      Colors.pink,
      Colors.amber,
      Colors.cyan,
      Colors.lime,
    ];

    // 速度特性配置
    final List<Map<String, dynamic>> speedProfiles = [
      {'maxSpeed': 15.0, 'acceleration': 0.7, 'friction': 1.2, 'name': '低速重球'},
      {'maxSpeed': 25.0, 'acceleration': 1.2, 'friction': 0.8, 'name': '高速轻球'},
      {'maxSpeed': 20.0, 'acceleration': 1.0, 'friction': 1.0, 'name': '标准球'},
      {'maxSpeed': 30.0, 'acceleration': 1.5, 'friction': 0.6, 'name': '极速球'},
      {'maxSpeed': 12.0, 'acceleration': 0.5, 'friction': 1.5, 'name': '超重球'},
      {'maxSpeed': 35.0, 'acceleration': 2.0, 'friction': 0.4, 'name': '闪电球'},
      {'maxSpeed': 18.0, 'acceleration': 0.9, 'friction': 1.1, 'name': '稳定球'},
      {'maxSpeed': 28.0, 'acceleration': 1.3, 'friction': 0.7, 'name': '敏捷球'},
      {'maxSpeed': 22.0, 'acceleration': 1.1, 'friction': 0.9, 'name': '平衡球'},
      {'maxSpeed': 40.0, 'acceleration': 2.5, 'friction': 0.3, 'name': '疯狂球'},
    ];

    for (int i = 0; i < 3; i++) {
      var profile = speedProfiles[i % speedProfiles.length];
      _balls.add(
        Ball(
          posX: (containerWidth - 60) / 2 + i * 20,
          posY: (containerHeight - 60) / 2 + i * 20,
          color: ballColors[i % ballColors.length],
          size: 40.0 + i * 10.0,
          maxSpeed: profile['maxSpeed'],
          accelerationFactor: profile['acceleration'],
          frictionFactor: profile['friction'],
        ),
      );
    }

    if (_balls.isNotEmpty) {
      _balls[0].isSelected = true;
    }
  }

  /// 重置小球位置到容器中心
  void _resetPosition() {
    setState(() {
      for (int i = 0; i < _balls.length; i++) {
        _balls[i] = _balls[i].copyWith(
          posX: (containerWidth - _balls[i].size) / 2 + i * 20,
          posY: (containerHeight - _balls[i].size) / 2 + i * 20,
          rotation: 0.0,
          velX: 0.0,
          velY: 0.0,
        );
      }
    });
  }

  /// 启动重力感应模式
  void _startGyroMode() {
    _accelerometerSubscription?.cancel();
    _physicsTimer?.cancel();

    _accelerometerSubscription = accelerometerEvents.listen((
      AccelerometerEvent event,
    ) {
      setState(() {
        _accelX = event.x;
        _accelY = event.y;
        _filteredAccelX = _filteredAccelX * 0.7 + _accelX * 0.3;
        _filteredAccelY = _filteredAccelY * 0.7 + _accelY * 0.3;
      });
    });

    _physicsTimer = Timer.periodic(const Duration(milliseconds: 16), (timer) {
      _updatePhysics();
    });
  }

  /// 物理模拟更新函数 - 增强版，支持不同速度特性
  void _updatePhysics() {
    setState(() {
      // 1. 对所有小球应用重力感应控制（考虑不同的加速度系数）
      _applyGravityToAllBalls();

      // 2. 更新所有小球位置
      _updateBallPositions();

      // 3. 处理边界碰撞
      _handleBoundaryCollisions();

      // 4. 处理小球之间的碰撞
      _handleBallCollisions();

      // 5. 更新视觉效果
      _updateVisualEffects();
    });
  }

  /// 对所有小球应用重力感应控制 - 增强版，考虑不同加速度系数
  void _applyGravityToAllBalls() {
    if (_balls.isEmpty) return;

    // 计算基于重力感应的加速度
    double baseAccelerationX = -_filteredAccelX * _sensitivity;
    double baseAccelerationY = _filteredAccelY * _sensitivity;

    // 限制最大基础加速度
    baseAccelerationX = baseAccelerationX.clamp(-3.0, 3.0);
    baseAccelerationY = baseAccelerationY.clamp(-3.0, 3.0);

    // 对每个小球应用不同的加速度系数
    for (var ball in _balls) {
      if (ball.isSpeedLocked) continue; // 如果速度锁定，跳过加速度应用

      double accelerationX = baseAccelerationX * ball.accelerationFactor;
      double accelerationY = baseAccelerationY * ball.accelerationFactor;

      ball.velX += accelerationX;
      ball.velY += accelerationY;

      // 应用不同的摩擦力系数
      double ballFriction = 1.0 - (1.0 - _baseFriction) * ball.frictionFactor;
      ball.velX *= ballFriction;
      ball.velY *= ballFriction;

      // 限制每个小球的最大速度
      if (ball.velX.abs() > ball.maxSpeed) {
        ball.velX = ball.velX.sign * ball.maxSpeed;
      }
      if (ball.velY.abs() > ball.maxSpeed) {
        ball.velY = ball.velY.sign * ball.maxSpeed;
      }

      // 微小速度归零
      if (ball.velX.abs() < 0.1) ball.velX = 0.0;
      if (ball.velY.abs() < 0.1) ball.velY = 0.0;
    }
  }

  /// 更新所有小球位置
  void _updateBallPositions() {
    for (var ball in _balls) {
      ball.posX += ball.velX;
      ball.posY += ball.velY;
    }
  }

  /// 处理边界碰撞
  void _handleBoundaryCollisions() {
    for (var ball in _balls) {
      // 左右边界碰撞
      if (ball.posX < 0) {
        ball.posX = 0;
        ball.velX = -ball.velX * 0.7;
      } else if (ball.posX > containerWidth - ball.size) {
        ball.posX = containerWidth - ball.size;
        ball.velX = -ball.velX * 0.7;
      }

      // 上下边界碰撞
      if (ball.posY < 0) {
        ball.posY = 0;
        ball.velY = -ball.velY * 0.7;
      } else if (ball.posY > containerHeight - ball.size) {
        ball.posY = containerHeight - ball.size;
        ball.velY = -ball.velY * 0.7;
      }
    }
  }

  /// 处理小球之间的碰撞
  void _handleBallCollisions() {
    for (int i = 0; i < _balls.length; i++) {
      for (int j = i + 1; j < _balls.length; j++) {
        Ball ball1 = _balls[i];
        Ball ball2 = _balls[j];

        if (_checkCollision(ball1, ball2)) {
          _resolveCollision(ball1, ball2);
        }
      }
    }
  }

  /// 检查两个小球是否碰撞
  bool _checkCollision(Ball ball1, Ball ball2) {
    double centerX1 = ball1.posX + ball1.size / 2;
    double centerY1 = ball1.posY + ball1.size / 2;
    double centerX2 = ball2.posX + ball2.size / 2;
    double centerY2 = ball2.posY + ball2.size / 2;

    double dx = centerX1 - centerX2;
    double dy = centerY1 - centerY2;
    double distance = sqrt(dx * dx + dy * dy);

    double minDistance = ball1.size / 2 + ball2.size / 2;

    return distance < minDistance;
  }

  /// 解决碰撞物理
  void _resolveCollision(Ball ball1, Ball ball2) {
    // 计算两球中心
    double centerX1 = ball1.posX + ball1.size / 2;
    double centerY1 = ball1.posY + ball1.size / 2;
    double centerX2 = ball2.posX + ball2.size / 2;
    double centerY2 = ball2.posY + ball2.size / 2;

    double dx = centerX1 - centerX2;
    double dy = centerY1 - centerY2;
    double distance = sqrt(dx * dx + dy * dy);

    if (distance == 0) return; // 避免除以零

    double minDistance = ball1.size / 2 + ball2.size / 2;
    double overlap = minDistance - distance;

    // 记录碰撞
    ball1.recordCollision(centerX1, centerY1);
    ball2.recordCollision(centerX2, centerY2);

    // 分离小球（防止重叠）
    double separationX = (dx / distance) * overlap / 2;
    double separationY = (dy / distance) * overlap / 2;

    ball1.posX += separationX;
    ball1.posY += separationY;
    ball2.posX -= separationX;
    ball2.posY -= separationY;

    // 计算碰撞法线
    double collisionAngle = atan2(dy, dx);
    double sinAngle = sin(collisionAngle);
    double cosAngle = cos(collisionAngle);

    // 转换到碰撞坐标系
    double ball1NormalVel = ball1.velX * cosAngle + ball1.velY * sinAngle;
    double ball1TangentVel = -ball1.velX * sinAngle + ball1.velY * cosAngle;

    double ball2NormalVel = ball2.velX * cosAngle + ball2.velY * sinAngle;
    double ball2TangentVel = -ball2.velX * sinAngle + ball2.velY * cosAngle;

    // 计算质量（与体积成正比）
    double mass1 = pow(ball1.size / 2, 3).toDouble();
    double mass2 = pow(ball2.size / 2, 3).toDouble();

    // 弹性碰撞公式（动量守恒 + 能量守恒）
    double ball1NormalVelAfter =
        (ball1NormalVel * (mass1 - mass2) + 2 * mass2 * ball2NormalVel) /
        (mass1 + mass2);
    double ball2NormalVelAfter =
        (ball2NormalVel * (mass2 - mass1) + 2 * mass1 * ball1NormalVel) /
        (mass1 + mass1);

    // 应用弹性系数
    ball1NormalVelAfter *= _collisionElasticity;
    ball2NormalVelAfter *= _collisionElasticity;

    // 转换回原始坐标系
    double ball1VelXAfter =
        ball1NormalVelAfter * cosAngle - ball1TangentVel * sinAngle;
    double ball1VelYAfter =
        ball1NormalVelAfter * sinAngle + ball1TangentVel * cosAngle;

    double ball2VelXAfter =
        ball2NormalVelAfter * cosAngle - ball2TangentVel * sinAngle;
    double ball2VelYAfter =
        ball2NormalVelAfter * sinAngle + ball2TangentVel * cosAngle;

    // 更新速度（考虑小球的最大速度限制）
    ball1.velX = ball1VelXAfter.clamp(-ball1.maxSpeed, ball1.maxSpeed);
    ball1.velY = ball1VelYAfter.clamp(-ball1.maxSpeed, ball1.maxSpeed);
    ball2.velX = ball2VelXAfter.clamp(-ball2.maxSpeed, ball2.maxSpeed);
    ball2.velY = ball2VelYAfter.clamp(-ball2.maxSpeed, ball2.maxSpeed);
  }

  /// 更新视觉效果
  void _updateVisualEffects() {
    for (var ball in _balls) {
      double totalVelocity = ball.currentSpeed;
      if (totalVelocity > 0.5) {
        // 旋转速度与小球速度特性相关
        double rotationSpeed = totalVelocity * 0.05 * ball.accelerationFactor;
        ball.rotation += rotationSpeed;
        if (ball.rotation > 4 * pi) ball.rotation -= 4 * pi;
      }
    }
  }

  /// 选择小球
  void _selectBall(int index) {
    setState(() {
      for (var ball in _balls) {
        ball.isSelected = false;
      }
      _selectedBallIndex = index;
      _balls[index].isSelected = true;
    });
  }

  /// 添加新小球 - 增强版，随机速度特性
  void _addBall() {
    if (_balls.length >= _maxBalls) return;

    setState(() {
      final List<Color> availableColors = [
        Colors.red,
        Colors.blue,
        Colors.green,
        Colors.orange,
        Colors.purple,
        Colors.teal,
        Colors.pink,
        Colors.amber,
      ];

      // 随机速度特性
      double maxSpeed = 15.0 + _random.nextDouble() * 25.0; // 15-40
      double acceleration = 0.5 + _random.nextDouble() * 2.0; // 0.5-2.5
      double friction = 0.3 + _random.nextDouble() * 1.2; // 0.3-1.5
      bool isSpeedLocked = _random.nextDouble() < 0.2; // 20%几率速度锁定

      double newX = _random.nextDouble() * (containerWidth - 60);
      double newY = _random.nextDouble() * (containerHeight - 60);
      double newSize = 30.0 + _random.nextDouble() * 30.0;

      // 检查重叠
      bool overlap = _balls.any((ball) {
        double dx = newX - ball.posX;
        double dy = newY - ball.posY;
        double distance = sqrt(dx * dx + dy * dy);
        return distance < (newSize + ball.size) / 2;
      });

      // 如果重叠，重新生成位置
      while (overlap && _balls.isNotEmpty) {
        newX = _random.nextDouble() * (containerWidth - newSize);
        newY = _random.nextDouble() * (containerHeight - newSize);

        overlap = _balls.any((ball) {
          double dx = newX - ball.posX;
          double dy = newY - ball.posY;
          double distance = sqrt(dx * dx + dy * dy);
          return distance < (newSize + ball.size) / 2;
        });
      }

      Ball newBall = Ball(
        posX: newX,
        posY: newY,
        color: availableColors[_balls.length % availableColors.length],
        size: newSize,
        maxSpeed: maxSpeed,
        accelerationFactor: acceleration,
        frictionFactor: friction,
        isSpeedLocked: isSpeedLocked,
        // 给一个随机初始速度
        velX: (_random.nextDouble() * 4 - 2) * acceleration,
        velY: (_random.nextDouble() * 4 - 2) * acceleration,
      );

      _balls.add(newBall);
      _selectBall(_balls.length - 1);
    });
  }

  /// 移除当前选中的小球
  void _removeBall() {
    if (_balls.isEmpty) return;

    setState(() {
      _balls.removeAt(_selectedBallIndex);
      if (_balls.isNotEmpty) {
        _selectedBallIndex = min(_selectedBallIndex, _balls.length - 1);
        _balls[_selectedBallIndex].isSelected = true;
      }
    });
  }

  /// 清空所有小球
  void _clearAllBalls() {
    setState(() {
      _balls.clear();
      _selectedBallIndex = 0;
    });
  }

  /// 给小球施加随机推力 - 增强版，考虑不同加速度系数
  void _addRandomForce() {
    setState(() {
      for (var ball in _balls) {
        if (ball.isSpeedLocked) continue;

        double forceMultiplier = ball.accelerationFactor;
        ball.velX += (_random.nextDouble() * 10 - 5) * forceMultiplier;
        ball.velY += (_random.nextDouble() * 10 - 5) * forceMultiplier;

        // 确保不超过最大速度
        ball.velX = ball.velX.clamp(-ball.maxSpeed, ball.maxSpeed);
        ball.velY = ball.velY.clamp(-ball.maxSpeed, ball.maxSpeed);
      }
    });
  }

  /// 切换速度锁定状态
  void _toggleSpeedLock() {
    if (_balls.isEmpty) return;

    setState(() {
      _balls[_selectedBallIndex] = _balls[_selectedBallIndex].copyWith(
        isSpeedLocked: !_balls[_selectedBallIndex].isSpeedLocked,
      );
    });
  }

  /// 修改选中小球的速度特性
  void _modifySelectedBallSpeed(
    double maxSpeedChange,
    double accelerationChange,
    double frictionChange,
  ) {
    if (_balls.isEmpty) return;

    setState(() {
      Ball currentBall = _balls[_selectedBallIndex];
      _balls[_selectedBallIndex] = currentBall.copyWith(
        maxSpeed: (currentBall.maxSpeed + maxSpeedChange).clamp(5.0, 50.0),
        accelerationFactor:
            (currentBall.accelerationFactor + accelerationChange).clamp(
              0.1,
              3.0,
            ),
        frictionFactor: (currentBall.frictionFactor + frictionChange).clamp(
          0.1,
          2.0,
        ),
      );
    });
  }

  /// 切换2D/1D模式
  void _toggle2DMode(bool is2D) {
    setState(() {
      _is2DMode = is2D;
      _resetPosition();
    });
  }

  // 计算属性
  int get _totalCollisions =>
      _balls.fold(0, (sum, ball) => sum + ball.collisionCount);
  double get _currentSpeed {
    if (_balls.isEmpty) return 0.0;
    return _balls[_selectedBallIndex].currentSpeed;
  }

  @override
  void dispose() {
    _accelerometerSubscription?.cancel();
    _physicsTimer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('多小球碰撞物理系统 - 不同速度'),
        backgroundColor: Colors.deepPurple,
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            children: [
              // 多小球控制面板
              _buildMultiBallControlPanel(),

              // 速度特性控制面板
              _buildSpeedControlPanel(),

              // 物理参数调节
              _buildPhysicsSettingsPanel(),

              // 碰撞统计面板
              _buildCollisionStatsPanel(),

              // 传感器数据
              _buildSensorDataPanel(),

              // 操作提示
              _buildInstructionPanel(),

              SizedBox(height: 10),

              // 游戏区域
              _buildGameArea(),

              SizedBox(height: 10),

              // 控制按钮
              _buildControlButtons(),

              SizedBox(height: 20),
            ],
          ),
        ),
      ),
    );
  }

  /// 构建多小球控制面板
  Widget _buildMultiBallControlPanel() {
    return Container(
      padding: EdgeInsets.all(12),
      margin: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.grey[50],
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: Colors.grey.shade300),
      ),
      child: Column(
        children: [
          Text(
            '多小球控制系统',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
          ),
          SizedBox(height: 8),

          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Text('小球数量: ${_balls.length}'),
              Text('当前选中: ${_balls.isNotEmpty ? _selectedBallIndex + 1 : 0}'),
            ],
          ),

          SizedBox(height: 8),

          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              ElevatedButton(
                onPressed: _addBall,
                style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
                child: Text('添加小球'),
              ),
              ElevatedButton(
                onPressed: _removeBall,
                style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
                child: Text('移除小球'),
              ),
              ElevatedButton(
                onPressed: _clearAllBalls,
                style: ElevatedButton.styleFrom(backgroundColor: Colors.orange),
                child: Text('清空所有'),
              ),
            ],
          ),

          SizedBox(height: 8),

          if (_balls.isNotEmpty) ...[
            Text('选择控制的小球:'),
            SizedBox(height: 4),
            Wrap(
              spacing: 5,
              children: List.generate(_balls.length, (index) {
                return ChoiceChip(
                  label: Text('${index + 1}'),
                  selected: _selectedBallIndex == index,
                  onSelected: (selected) => _selectBall(index),
                  backgroundColor: _balls[index].color.withOpacity(0.3),
                  selectedColor: _balls[index].color,
                  labelStyle: TextStyle(color: Colors.white),
                );
              }),
            ),
          ],
        ],
      ),
    );
  }

  /// 构建速度特性控制面板
  Widget _buildSpeedControlPanel() {
    if (_balls.isEmpty) return SizedBox();

    Ball selectedBall = _balls[_selectedBallIndex];

    return Container(
      padding: EdgeInsets.all(12),
      margin: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.purple[50],
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: Colors.purple.shade300),
      ),
      child: Column(
        children: [
          Text(
            '小球速度特性控制',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
          ),
          SizedBox(height: 8),

          // 速度锁定状态
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text('速度锁定: ${selectedBall.isSpeedLocked ? "已锁定" : "未锁定"}'),
              ElevatedButton(
                onPressed: _toggleSpeedLock,
                style: ElevatedButton.styleFrom(
                  backgroundColor: selectedBall.isSpeedLocked
                      ? Colors.red
                      : Colors.green,
                ),
                child: Text(selectedBall.isSpeedLocked ? '解锁速度' : '锁定速度'),
              ),
            ],
          ),

          SizedBox(height: 8),

          // 速度特性显示
          Wrap(
            spacing: 16,
            runSpacing: 8,
            children: [
              _buildSpeedInfoItem(
                '最大速度',
                '${selectedBall.maxSpeed.toStringAsFixed(1)}',
                Colors.red,
              ),
              _buildSpeedInfoItem(
                '加速度',
                '${selectedBall.accelerationFactor.toStringAsFixed(1)}x',
                Colors.green,
              ),
              _buildSpeedInfoItem(
                '摩擦力',
                '${selectedBall.frictionFactor.toStringAsFixed(1)}x',
                Colors.blue,
              ),
              _buildSpeedInfoItem(
                '当前速度',
                '${selectedBall.currentSpeed.toStringAsFixed(1)}',
                Colors.orange,
              ),
              _buildSpeedInfoItem(
                '状态',
                selectedBall.speedDescription,
                Colors.purple,
              ),
            ],
          ),

          SizedBox(height: 8),

          // 速度调整按钮
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              ElevatedButton(
                onPressed: () => _modifySelectedBallSpeed(2.0, 0, 0),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.red[300],
                ),
                child: Text('加速+'),
              ),
              ElevatedButton(
                onPressed: () => _modifySelectedBallSpeed(-2.0, 0, 0),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue[300],
                ),
                child: Text('减速-'),
              ),
              ElevatedButton(
                onPressed: () => _modifySelectedBallSpeed(0, 0.2, 0),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.green[300],
                ),
                child: Text('灵敏+'),
              ),
              ElevatedButton(
                onPressed: () => _modifySelectedBallSpeed(0, -0.2, 0),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.orange[300],
                ),
                child: Text('灵敏-'),
              ),
            ],
          ),
        ],
      ),
    );
  }

  /// 构建速度信息项
  Widget _buildSpeedInfoItem(String title, String value, Color color) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      decoration: BoxDecoration(
        color: color.withOpacity(0.1),
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: color.withOpacity(0.3)),
      ),
      child: Column(
        children: [
          Text(title, style: TextStyle(fontSize: 12, color: color)),
          Text(
            value,
            style: TextStyle(fontWeight: FontWeight.bold, color: color),
          ),
        ],
      ),
    );
  }

  /// 构建物理参数调节面板
  Widget _buildPhysicsSettingsPanel() {
    return Container(
      padding: EdgeInsets.all(12),
      margin: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.green[50],
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: Colors.green.shade300),
      ),
      child: Column(
        children: [
          Text('物理参数调节', style: TextStyle(fontWeight: FontWeight.bold)),
          SizedBox(height: 8),

          Row(
            children: [
              Text('弹性: ${_collisionElasticity.toStringAsFixed(2)}'),
              Expanded(
                child: Slider(
                  value: _collisionElasticity,
                  min: 0.1,
                  max: 1.0,
                  divisions: 9,
                  onChanged: (value) {
                    setState(() {
                      _collisionElasticity = value;
                    });
                  },
                ),
              ),
            ],
          ),

          Row(
            children: [
              Text('基础摩擦: ${_baseFriction.toStringAsFixed(2)}'),
              Expanded(
                child: Slider(
                  value: _baseFriction,
                  min: 0.8,
                  max: 0.99,
                  divisions: 19,
                  onChanged: (value) {
                    setState(() {
                      _baseFriction = value;
                    });
                  },
                ),
              ),
            ],
          ),

          Row(
            children: [
              Text('灵敏度: ${_sensitivity.toStringAsFixed(2)}'),
              Expanded(
                child: Slider(
                  value: _sensitivity,
                  min: 0.1,
                  max: 2.0,
                  divisions: 19,
                  onChanged: (value) {
                    setState(() {
                      _sensitivity = value;
                    });
                  },
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  /// 构建碰撞统计面板
  Widget _buildCollisionStatsPanel() {
    return Container(
      padding: EdgeInsets.all(12),
      margin: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.blueGrey[50],
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: Colors.blueGrey.shade300),
      ),
      child: Column(
        children: [
          Text('碰撞统计', style: TextStyle(fontWeight: FontWeight.bold)),
          SizedBox(height: 6),
          Text('总碰撞次数: $_totalCollisions'),
          Text('小球数量: ${_balls.length}'),
          if (_balls.isNotEmpty) ...[
            Text('选中小球碰撞: ${_balls[_selectedBallIndex].collisionCount}'),
            Container(
              height: 20,
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: _balls[_selectedBallIndex].collisionHistory.length,
                itemBuilder: (context, index) {
                  return Container(
                    width: 4,
                    height: 4,
                    margin: EdgeInsets.symmetric(horizontal: 1),
                    decoration: BoxDecoration(
                      color: Colors.red,
                      shape: BoxShape.circle,
                    ),
                  );
                },
              ),
            ),
          ],
        ],
      ),
    );
  }

  /// 构建传感器数据面板
  Widget _buildSensorDataPanel() {
    return Container(
      padding: EdgeInsets.all(12),
      margin: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.grey[50],
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: Colors.grey.shade300),
      ),
      child: Column(
        children: [
          Text('传感器数据', style: TextStyle(fontWeight: FontWeight.bold)),
          SizedBox(height: 6),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Column(
                children: [
                  Text('X轴: ${_filteredAccelX.toStringAsFixed(2)}'),
                  Text(
                    '速度X: ${_balls.isNotEmpty ? _balls[_selectedBallIndex].velX.toStringAsFixed(1) : "0.0"}',
                  ),
                ],
              ),
              Column(
                children: [
                  Text('Y轴: ${_filteredAccelY.toStringAsFixed(2)}'),
                  Text(
                    '速度Y: ${_balls.isNotEmpty ? _balls[_selectedBallIndex].velY.toStringAsFixed(1) : "0.0"}',
                  ),
                ],
              ),
            ],
          ),
          SizedBox(height: 6),
          Text(
            '合速度: ${_currentSpeed.toStringAsFixed(1)} | 模式: ${_is2DMode ? "2D自由移动" : "1D水平移动"}',
          ),
        ],
      ),
    );
  }

  /// 构建操作提示面板
  Widget _buildInstructionPanel() {
    return Container(
      padding: EdgeInsets.all(12),
      margin: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: _is2DMode ? Colors.purple.shade50 : Colors.blue.shade50,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        _is2DMode
            ? '📱 倾斜手机控制所有小球在二维空间移动\n每个小球有不同的速度特性！\n←→ 左右移动  ↑↓ 上下移动'
            : '📱 左右倾斜手机控制小球水平移动',
        textAlign: TextAlign.center,
        style: TextStyle(color: Colors.grey[700]),
      ),
    );
  }

  /// 构建游戏区域
  Widget _buildGameArea() {
    return Container(
      width: containerWidth,
      height: containerHeight,
      margin: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.grey[100],
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: Colors.grey.shade400, width: 2),
        boxShadow: [
          BoxShadow(color: Colors.black26, blurRadius: 8, offset: Offset(2, 2)),
        ],
      ),
      child: Stack(
        children: [
          CustomPaint(painter: _GridPainter()),

          Center(
            child: Container(
              width: 2,
              height: containerHeight,
              color: Colors.grey.shade300.withOpacity(0.5),
            ),
          ),
          Center(
            child: Container(
              width: containerWidth,
              height: 2,
              color: Colors.grey.shade300.withOpacity(0.5),
            ),
          ),

          ..._buildAllBalls(),

          if (_balls.isNotEmpty) _buildSelectionIndicator(),
        ],
      ),
    );
  }

  /// 构建所有小球 - 增强版，显示速度特性
  List<Widget> _buildAllBalls() {
    return _balls.asMap().entries.map((entry) {
      int index = entry.key;
      Ball ball = entry.value;
      return _buildBallWithEffects(ball, index);
    }).toList();
  }

  /// 构建带效果的小球 - 增强版，显示速度信息
  /// 构建带效果的小球 - 修复阴影问题
  Widget _buildBallWithEffects(Ball ball, int index) {
    double glowIntensity = min(ball.collisionCount.toDouble() * 0.1, 1.0);

    // 根据速度特性调整发光效果
    double speedGlow = (ball.currentSpeed / ball.maxSpeed) * 0.5;
    double totalGlow = max(glowIntensity, speedGlow);

    return Positioned(
      left: ball.posX,
      top: ball.posY,
      child: GestureDetector(
        onTap: () => _selectBall(index),
        child: Stack(
          children: [
            if (totalGlow > 0)
              Container(
                width: ball.size + totalGlow * 20,
                height: ball.size + totalGlow * 20,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: ball.color.withOpacity(totalGlow * 0.3),
                ),
              ),

            // 使用Material widget来获得正确的圆形阴影
            Material(
              elevation: 8.0,
              shadowColor: Colors.black.withOpacity(0.6),
              shape: CircleBorder(),
              child: Transform.rotate(
                angle: ball.rotation,
                child: Container(
                  width: ball.size,
                  height: ball.size,
                  decoration: BoxDecoration(
                    color: ball.color,
                    shape: BoxShape.circle,
                    gradient: RadialGradient(
                      colors: [
                        ball.color.withOpacity(0.8),
                        ball.color.withOpacity(0.4),
                      ],
                    ),
                  ),
                  child: Stack(
                    children: [
                      Positioned(
                        top: ball.size * 0.2,
                        left: ball.size * 0.2,
                        child: Container(
                          width: ball.size * 0.2,
                          height: ball.size * 0.2,
                          decoration: BoxDecoration(
                            color: Colors.white.withOpacity(0.8),
                            shape: BoxShape.circle,
                          ),
                        ),
                      ),

                      Center(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Text(
                              '${index + 1}',
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: ball.size * 0.3,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            if (ball.collisionCount > 0)
                              Text(
                                '${ball.collisionCount}',
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: ball.size * 0.15,
                                ),
                              ),
                            // 显示速度锁定图标
                            if (ball.isSpeedLocked)
                              Icon(
                                Icons.lock,
                                color: Colors.white,
                                size: ball.size * 0.2,
                              ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),

            // 选中的高亮效果
            if (ball.isSelected)
              Container(
                width: ball.size + 10,
                height: ball.size + 10,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  border: Border.all(color: Colors.yellow, width: 3),
                ),
              ),

            // 速度锁定的红色光环
            if (ball.isSpeedLocked)
              Container(
                width: ball.size + 15,
                height: ball.size + 15,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  border: Border.all(
                    color: Colors.red.withOpacity(0.8),
                    width: 2,
                  ),
                ),
              ),

            // 速度指示器
            Positioned(
              bottom: -5,
              left: 0,
              right: 0,
              child: Container(
                height: 4,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(2),
                  color: Colors.grey[300],
                ),
                child: FractionallySizedBox(
                  alignment: Alignment.centerLeft,
                  widthFactor: ball.currentSpeed / ball.maxSpeed,
                  child: Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(2),
                      gradient: LinearGradient(
                        colors: [Colors.green, Colors.yellow, Colors.red],
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// 构建选择指示器
  Widget _buildSelectionIndicator() {
    Ball selectedBall = _balls[_selectedBallIndex];
    return Positioned(
      left: selectedBall.posX - 5,
      top: selectedBall.posY - 5,
      child: Container(
        width: selectedBall.size + 10,
        height: selectedBall.size + 10,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          border: Border.all(
            color: selectedBall.isSpeedLocked ? Colors.red : Colors.yellow,
            width: 2,
          ),
        ),
      ),
    );
  }

  /// 构建控制按钮
  Widget _buildControlButtons() {
    return Wrap(
      spacing: 10,
      runSpacing: 10,
      children: [
        ElevatedButton(
          onPressed: _resetPosition,
          style: ElevatedButton.styleFrom(backgroundColor: Colors.orange),
          child: Text('重置位置'),
        ),
        ElevatedButton(
          onPressed: () {
            setState(() {
              for (var ball in _balls) {
                ball.velX = 0.0;
                ball.velY = 0.0;
              }
            });
          },
          style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
          child: Text('急停'),
        ),
        ElevatedButton(
          onPressed: _addRandomForce,
          style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
          child: Text('随机推力'),
        ),
        ElevatedButton(
          onPressed: () => _toggle2DMode(true),
          style: ElevatedButton.styleFrom(
            backgroundColor: _is2DMode ? Colors.purple : Colors.grey,
          ),
          child: Text('2D模式'),
        ),
        ElevatedButton(
          onPressed: () => _toggle2DMode(false),
          style: ElevatedButton.styleFrom(
            backgroundColor: !_is2DMode ? Colors.blue : Colors.grey,
          ),
          child: Text('1D模式'),
        ),
      ],
    );
  }
}

/// 网格背景绘制类
class _GridPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.grey.shade300.withOpacity(0.3)
      ..strokeWidth = 0.5;

    for (double x = 0; x < size.width; x += 20) {
      canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint);
    }

    for (double y = 0; y < size.height; y += 20) {
      canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
